import 'dart:math' as math;
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import '../models/period_model.dart';
import '../di/service_locator.dart';
import 'data_service.dart';
import 'database_helper.dart';


class PredictionService {
  static final PredictionService _instance = PredictionService._internal();
  final DataService _dataService = ServiceLocator().get<DataService>();
  final DatabaseHelper _dbHelper = DatabaseHelper.instance;
  
  
  final Map<String, dynamic> _predictionCache = {};
  DateTime? _cacheTimestamp;
  static const Duration _cacheValidity = Duration(minutes: 10); 

  
  factory PredictionService() => _instance;
  
  PredictionService._internal();
  
  
  bool _isCacheValid() {
    if (_cacheTimestamp == null) return false;
    return DateTime.now().difference(_cacheTimestamp!) < _cacheValidity;
  }
  
  
  void clearCache() {
    _predictionCache.clear();
    _cacheTimestamp = null;
  }
  
  
  // predictCycle 方法在文件后面有更新版本，此处省略旧实现
  
  
  DateTime _advancedNextPeriodPrediction(List<PeriodModel> periodRecords, UserProfile userProfile) {
    
    if (periodRecords.length < 2) {
      return periodRecords.first.date.add(Duration(days: userProfile.cycleLength));
    }
    
    
    final cycleLengths = <int>[];
    for (int i = 1; i < periodRecords.length; i++) {
      final daysBetween = periodRecords[i-1].date.difference(periodRecords[i].date).inDays;
      if (daysBetween >= 21 && daysBetween <= 45) { 

        cycleLengths.add(daysBetween);
      }
    }
    
    if (cycleLengths.isEmpty) {
      return periodRecords.first.date.add(Duration(days: userProfile.cycleLength));
    }
    
    
    double weightedSum = 0;
    double totalWeight = 0;
    
    
    final wma = _calculateWeightedMovingAverage(cycleLengths);
    weightedSum += wma * 0.4; 

    totalWeight += 0.4;
    
    
    final es = _calculateExponentialSmoothing(cycleLengths);
    weightedSum += es * 0.3; 

    totalWeight += 0.3;
    
    
    final lr = _calculateLinearRegression(cycleLengths);
    weightedSum += lr * 0.2; 

    totalWeight += 0.2;
    
    
    weightedSum += userProfile.cycleLength * 0.1; 

    totalWeight += 0.1;
    
    
    final predictedCycleLength = (weightedSum / totalWeight).round();
    
    
    final adjustedLength = _applyIndividualFactors(predictedCycleLength, periodRecords, userProfile);
    
    return periodRecords.first.date.add(Duration(days: adjustedLength));
  }
  
  
  DateTime _advancedOvulationPrediction(
      DateTime nextPeriodDate, 
      List<PeriodModel> periodRecords, 
      UserProfile userProfile) {
    
    
    int daysBeforePeriod = 14; 

    
    
    if (periodRecords.length >= 3) {
      
    
    
    
    
    final stdDev = _calculateCycleStandardDeviation(periodRecords);
      
      
      if (stdDev <= 2) {
        daysBeforePeriod = 14;
      } else if (stdDev <= 4) {
        
        final age = _calculateAge(userProfile.birthDate);
        if (age < 25) {
          daysBeforePeriod = 13; 

        } else if (age > 35) {
          daysBeforePeriod = 15; 

        }
      } else {
        
        daysBeforePeriod = 14 + (math.Random().nextInt(3) - 1); 

      }
    }
    
    return nextPeriodDate.subtract(Duration(days: daysBeforePeriod));
  }
  
  
  List<DateTime> _calculateAdvancedFertilityWindow(
      DateTime ovulationDate, 
      List<PeriodModel> periodRecords, 
      UserProfile userProfile) {
    
    final window = <DateTime>[];
    
    
    int startOffset = -5;
    int endOffset = 1;
    
    
    if (userProfile.healthConditions.isNotEmpty) {
      
      if (userProfile.healthConditions.contains('多囊卵巢')) {
        startOffset = -7; 

      }
    }
    
    
    if (periodRecords.length >= 3) {
      final stdDev = _calculateCycleStandardDeviation(periodRecords);
      if (stdDev > 4) {
        
        startOffset = -7;
        endOffset = 2;
      }
    }
    
    
    for (int i = startOffset; i <= endOffset; i++) {
      window.add(ovulationDate.add(Duration(days: i)));
    }
    
    return window;
  }
  
  
  int _calculatePredictionConfidence(List<PeriodModel> periodRecords, UserProfile userProfile) {
    
    int confidence = 50;
    
    
    if (periodRecords.length >= 3) {
      confidence += 15;
      if (periodRecords.length >= 6) {
        confidence += 15;
        if (periodRecords.length >= 12) {
          confidence += 10;
        }
      }
    }
    
    
    if (periodRecords.length >= 3) {
      final stdDev = _calculateCycleStandardDeviation(periodRecords);
      if (stdDev <= 1) {
        confidence += 20;
      } else if (stdDev <= 2) {
        confidence += 15;
      } else if (stdDev <= 3) {
        confidence += 10;
      } else if (stdDev <= 5) {
        confidence += 5;
      }
    }
    
    
    if (userProfile.height > 0 && userProfile.weight > 0) {
      confidence += 5;
    }
    
    
    return confidence.clamp(0, 98); 

  }
  
  
  // 高级怀孕概率计算
  Map<DateTime, double> _calculateAdvancedPregnancyRates(DateTime ovulationDate, UserProfile userProfile) {
    final rates = <DateTime, double>{};
    final now = DateTime.now();
    
    // 计算排卵日前后多天的怀孕概率
    for (int i = -10; i <= 20; i++) {
      final date = ovulationDate.add(Duration(days: i));
      if (date.isBefore(now.subtract(Duration(days: 30))) || 
          date.isAfter(now.add(Duration(days: 60)))) {
        continue;
      }
      
      final daysFromOvulation = i;
      double baseRate = 0.0;
      
      // 基于研究数据的受孕概率模型
      if (daysFromOvulation == 0) {
        baseRate = 33.0;  // 排卵当天
      } else if (daysFromOvulation == -1) {
        baseRate = 31.0;  // 排卵前1天
      } else if (daysFromOvulation == 1) {
        baseRate = 27.0;  // 排卵后1天
      } else if (daysFromOvulation == -2) {
        baseRate = 25.0;  // 排卵前2天
      } else if (daysFromOvulation == -3) {
        baseRate = 18.0;  // 排卵前3天
      } else if (daysFromOvulation == -4) {
        baseRate = 12.0;  // 排卵前4天
      } else if (daysFromOvulation == -5) {
        baseRate = 5.0;   // 排卵前5天
      } else if (daysFromOvulation == 2) {
        baseRate = 15.0;  // 排卵后2天
      } else {
        baseRate = 3.2;   // 其他天数
      }
      
      // 年龄因素调整
      final age = _calculateAge(userProfile.birthDate);
      if (age > 35) {
        baseRate *= 0.8;  // 35岁以上概率降低20%
      } else if (age > 40) {
        baseRate *= 0.6;  // 40岁以上概率降低40%
      } else if (age < 20) {
        baseRate *= 0.9;  // 20岁以下概率略低
      }
      
      // 健康状况调整
      if (userProfile.healthConditions.isNotEmpty) {
        for (var condition in userProfile.healthConditions) {
          if (condition.contains('多囊')) {
            baseRate *= 0.6;  // 多囊卵巢综合征影响更大
          } else if (condition.contains('甲状腺')) {
            baseRate *= 0.8;  // 甲状腺问题
          } else if (condition.contains('不孕')) {
            baseRate *= 0.7;  // 不孕问题
          } else if (condition.contains('糖尿病')) {
            baseRate *= 0.85; // 糖尿病
          }
        }
      }
      
      // BMI因素调整
      if (userProfile.height > 0 && userProfile.weight > 0) {
        final heightInMeters = userProfile.height / 100;
        final bmi = userProfile.weight / (heightInMeters * heightInMeters);
        
        if (bmi < 18.5 || bmi > 30) {
          baseRate *= 0.8;  // BMI异常影响受孕
        }
      }
      
      // 生活习惯调整（如果未来添加）
      
      rates[date] = baseRate;
    }
    
    return rates;
  }
  
  
  // 基于贝叶斯模型的预测方法
  Future<PredictionResult> predictWithBayesianModel(UserProfile userProfile) async {
    final records = await _dataService.loadPeriodRecords();
    final periodRecords = records.where((r) => r.isPeriod).toList()
      ..sort((a, b) => b.date.compareTo(a.date));
    
    if (periodRecords.length < 3) {
      // 数据不足时回退到常规预测
      return predictCycle(userProfile);
    }
    
    // 计算历史周期统计
    final cycleLengths = <int>[];
    for (int i = 1; i < periodRecords.length; i++) {
      final daysBetween = periodRecords[i-1].date.difference(periodRecords[i].date).inDays;
      if (daysBetween >= 21 && daysBetween <= 45) {
        cycleLengths.add(daysBetween);
      }
    }
    
    // 贝叶斯先验概率（基于人群数据）
    final Map<int, double> priorProbabilities = {
      26: 0.05,
      27: 0.08,
      28: 0.15,
      29: 0.12,
      30: 0.10,
      31: 0.08,
      32: 0.06,
      // 其他天数的先验概率
    };
    
    // 计算似然度
    final Map<int, double> likelihoods = {};
    final stdDev = _calculateStandardDeviation(cycleLengths);
    
    for (int possibleLength = 21; possibleLength <= 45; possibleLength++) {
      double likelihood = 1.0;
      for (int length in cycleLengths) {
        // 高斯分布计算似然度
        final exponent = -0.5 * math.pow((length - possibleLength) / stdDev, 2);
        likelihood *= math.exp(exponent) / (stdDev * math.sqrt(2 * math.pi));
      }
      likelihoods[possibleLength] = likelihood;
    }
    
    // 计算后验概率
    final Map<int, double> posteriorProbabilities = {};
    double totalProbability = 0.0;
    
    for (int possibleLength = 21; possibleLength <= 45; possibleLength++) {
      final prior = priorProbabilities[possibleLength] ?? 0.001;
      final likelihood = likelihoods[possibleLength] ?? 0.0;
      posteriorProbabilities[possibleLength] = prior * likelihood;
      totalProbability += posteriorProbabilities[possibleLength]!;
    }
    
    // 归一化后验概率
    for (int possibleLength in posteriorProbabilities.keys) {
      posteriorProbabilities[possibleLength] = 
          posteriorProbabilities[possibleLength]! / totalProbability;
    }
    
    // 选择后验概率最高的周期长度
    double maxProbability = 0.0;
    
    posteriorProbabilities.forEach((length, probability) {
      if (probability > maxProbability) {
        maxProbability = probability;
      }
    });
    
    // 计算加权平均周期长度（更准确）
    double weightedCycleLength = 0.0;
    double weightSum = 0.0;
    
    posteriorProbabilities.forEach((length, probability) {
      weightedCycleLength += length * probability;
      weightSum += probability;
    });
    
    final predictedCycleLength = (weightedCycleLength / weightSum).round();
    
    // 预测下次经期
    final nextPeriodDate = periodRecords.first.date.add(Duration(days: predictedCycleLength));
    
    // 预测排卵日（考虑个体差异）
    final ovulationOffset = _calculateIndividualOvulationOffset(periodRecords, userProfile);
    final ovulationDate = nextPeriodDate.subtract(Duration(days: ovulationOffset));
    
    // 计算易孕期
    final fertilityWindow = _calculateAdvancedFertilityWindow(ovulationDate, periodRecords, userProfile);
    
    // 计算可信度（基于后验概率和数据量）
    int confidenceLevel = 50 + (maxProbability * 20).round();
    if (periodRecords.length >= 6) confidenceLevel += 10;
    if (periodRecords.length >= 12) confidenceLevel += 10;
    if (stdDev <= 1) confidenceLevel += 20;
    confidenceLevel = confidenceLevel.clamp(0, 98);
    
    // 计算怀孕概率
    final pregnancyRates = _calculateAdvancedPregnancyRates(ovulationDate, userProfile);
    
    return PredictionResult(
      nextPeriodDate: nextPeriodDate,
      ovulationDate: ovulationDate,
      fertilityWindow: fertilityWindow,
      confidenceLevel: confidenceLevel,
      pregnancyRates: pregnancyRates,
      predictedCycleLength: predictedCycleLength,
    );
  }
  
  // 计算个体排卵偏移（基于历史数据和用户特征）
  int _calculateIndividualOvulationOffset(List<PeriodModel> periodRecords, UserProfile userProfile) {
    // 基础值14天
    int baseOffset = 14;
    
    // 如果有足够的历史数据，计算实际排卵偏移
    if (periodRecords.length >= 6) {
      // 这里可以集成体温数据、排卵试纸数据等
      // 简化实现：基于周期长度调整
      final cycleLengths = <int>[];
      for (int i = 1; i < periodRecords.length; i++) {
        final days = periodRecords[i-1].date.difference(periodRecords[i].date).inDays;
        if (days >= 21 && days <= 45) cycleLengths.add(days);
      }
      
      if (cycleLengths.isNotEmpty) {
        final avgCycleLength = cycleLengths.reduce((a, b) => a + b) / cycleLengths.length;
        // 周期较长的人排卵可能稍晚
        if (avgCycleLength > 30) {
          baseOffset = 15;
        } else if (avgCycleLength < 26) {
          baseOffset = 13;
        }
      }
    }
    
    // 考虑用户健康状况
    if (userProfile.healthConditions.contains('多囊')) {
      baseOffset += 1;
    }
    
    // 考虑年龄
    final age = _calculateAge(userProfile.birthDate);
    if (age > 35) {
      baseOffset += 1;
    }
    
    return baseOffset;
  }
  
  // 计算标准差（通用方法）
  double _calculateStandardDeviation(List<int> values) {
    if (values.length < 2) return 0.0;
    
    final mean = values.reduce((a, b) => a + b) / values.length;
    double sumSquaredDiff = 0;
    
    for (var value in values) {
      sumSquaredDiff += math.pow(value - mean, 2);
    }
    
    return math.sqrt(sumSquaredDiff / values.length);
  }
  
  // 整合症状数据的预测方法
  Future<PredictionResult> predictWithSymptoms(UserProfile userProfile) async {
    // 先进行贝叶斯预测
    final basePrediction = await predictWithBayesianModel(userProfile);
    
    try {
      // 获取症状数据
      final symptoms = await _dbHelper.queryAllRows('symptom');
      if (symptoms.isEmpty) {
        return basePrediction;
      }
      
      // 分析症状模式
      Map<String, List<int>> symptomDaysBeforePeriod = {};
      
      final records = await _dataService.loadPeriodRecords();
      final periodRecords = records.where((r) => r.isPeriod).toList()
        ..sort((a, b) => b.date.compareTo(a.date));
      
      // 收集症状出现时间与经期的关系
      for (var symptom in symptoms) {
        DateTime symptomDate = DateTime.parse(symptom['date'] as String);
        String symptomType = symptom['type'] as String;
        
        // 找到最近的经期开始日期
        DateTime? nearestPeriodStart;
        for (var period in periodRecords) {
          if (symptomDate.isBefore(period.date)) {
            nearestPeriodStart = period.date;
            break;
          }
        }
        
        if (nearestPeriodStart != null) {
          int daysBeforePeriod = nearestPeriodStart.difference(symptomDate).inDays;
          if (daysBeforePeriod >= 0 && daysBeforePeriod <= 7) { // 只考虑经期前7天的症状
            if (!symptomDaysBeforePeriod.containsKey(symptomType)) {
              symptomDaysBeforePeriod[symptomType] = [];
            }
            symptomDaysBeforePeriod[symptomType]!.add(daysBeforePeriod);
          }
        }
      }
      
      // 检查最近的症状
      DateTime today = DateTime.now();
      List<Map<String, dynamic>> recentSymptoms = symptoms.where((s) {
        DateTime symptomDate = DateTime.parse(s['date'] as String);
        return symptomDate.isAfter(today.subtract(Duration(days: 7)));
      }).toList();
      
      // 如果有最近症状，可以微调预测
      if (recentSymptoms.isNotEmpty) {
        DateTime nextPeriodDate = basePrediction.nextPeriodDate;
        
        for (var symptom in recentSymptoms) {
          String symptomType = symptom['type'] as String;
          if (symptomDaysBeforePeriod.containsKey(symptomType)) {
            List<int> days = symptomDaysBeforePeriod[symptomType]!;
            if (days.isNotEmpty) {
              int avgDaysBefore = days.reduce((a, b) => a + b) ~/ days.length;
              DateTime predictedBySymptom = DateTime.parse(symptom['date'] as String)
                  .add(Duration(days: avgDaysBefore));
              
              // 使用加权平均调整预测日期
              int daysDiff = (predictedBySymptom.difference(nextPeriodDate).inDays).abs();
              if (daysDiff <= 3) { // 只考虑误差在3天内的症状预测
                nextPeriodDate = DateTime(
                  nextPeriodDate.year,
                  nextPeriodDate.month,
                  nextPeriodDate.day + (predictedBySymptom.difference(nextPeriodDate).inDays) ~/ 2
                );
              }
            }
          }
        }
        
        // 如果调整了经期日期，更新相关预测
        if (nextPeriodDate != basePrediction.nextPeriodDate) {
          final ovulationDate = nextPeriodDate.subtract(Duration(days: 14));
          final fertilityWindow = _calculateAdvancedFertilityWindow(
              ovulationDate, periodRecords, userProfile);
          final pregnancyRates = _calculateAdvancedPregnancyRates(ovulationDate, userProfile);
          
          // 提高可信度（因为有症状数据支持）
          int adjustedConfidence = math.min(98, basePrediction.confidenceLevel + 5);
          
          return PredictionResult(
            nextPeriodDate: nextPeriodDate,
            ovulationDate: ovulationDate,
            fertilityWindow: fertilityWindow,
            confidenceLevel: adjustedConfidence,
            pregnancyRates: pregnancyRates,
            predictedCycleLength: nextPeriodDate.difference(periodRecords.first.date).inDays,
          );
        }
      }
    } catch (e) {
      debugPrint('症状整合预测失败: $e');
    }
    
    return basePrediction;
  }
  
  // 主预测方法 - 整合多种预测模型
  Future<PredictionResult> predictCycle(UserProfile? userProfile, {bool forceRecalculate = false}) async {
    // 缓存逻辑保持不变
    if (!forceRecalculate && _isCacheValid() && _predictionCache.containsKey('predictionResult')) {
      debugPrint('使用缓存的预测结果');
      return _predictionCache['predictionResult'] as PredictionResult;
    }
    
    // 确保用户档案存在
    if (userProfile == null) {
      debugPrint('用户档案为空，创建默认用户档案');
      userProfile = UserProfile(
        name: '默认用户',
        birthDate: DateTime.now().subtract(const Duration(days: 25 * 365)),
        height: 160,
        weight: 55,
        bloodType: 'A',
        currentMode: 'period',
        cycleLength: 28,
        periodLength: 5,
        lastPeriodDate: DateTime.now().subtract(const Duration(days: 14)),
        healthConditions: [],
        notificationsEnabled: true,
        darkMode: false,
        isUsingBirthControl: false
      );
    }
    
    // 获取记录
    final records = await _dataService.loadPeriodRecords();
    final periodRecords = records.where((r) => r.isPeriod).toList()
      ..sort((a, b) => b.date.compareTo(a.date));
    
    // 如果记录不足，创建模拟数据
    if (periodRecords.isEmpty) {
      debugPrint('经期记录为空，创建模拟数据进行预测');
      final now = DateTime.now();
      
      periodRecords.add(PeriodModel(
        date: now.subtract(const Duration(days: 14)),
        isPeriod: true,
        isOvulation: false,
        isToday: false,
        isPredictedPeriod: false,
        isPossiblePeriod: false,
      ));
      periodRecords.add(PeriodModel(
        date: now.subtract(const Duration(days: 14 + 28)),
        isPeriod: true,
        isOvulation: false,
        isToday: false,
        isPredictedPeriod: false,
        isPossiblePeriod: false,
      ));
      periodRecords.add(PeriodModel(
        date: now.subtract(const Duration(days: 14 + 28 * 2)),
        isPeriod: true,
        isOvulation: false,
        isToday: false,
        isPredictedPeriod: false,
        isPossiblePeriod: false,
      ));
    }
    
    // 选择合适的预测模型
    PredictionResult result;
    if (periodRecords.length >= 3) {
      try {
        // 优先使用症状整合预测
        result = await predictWithSymptoms(userProfile);
      } catch (e) {
        debugPrint('症状整合预测失败，回退到贝叶斯模型: $e');
        try {
          // 然后尝试贝叶斯模型
          result = await predictWithBayesianModel(userProfile);
        } catch (e) {
          debugPrint('贝叶斯模型失败，回退到高级算法: $e');
          // 最后使用原有的高级算法
          result = _fallbackPrediction(periodRecords, userProfile);
        }
      }
    } else {
      // 数据不足时使用简化预测
      result = _fallbackPrediction(periodRecords, userProfile);
    }
    
    // 缓存结果
    _predictionCache['predictionResult'] = result;
    _cacheTimestamp = DateTime.now();
    
    debugPrint('完成预测: 下次经期=${result.nextPeriodDate}, 排卵日=${result.ovulationDate}, 可信度=${result.confidenceLevel}%');
    
    return result;
  }
  
  // 回退预测方法
  PredictionResult _fallbackPrediction(List<PeriodModel> periodRecords, UserProfile userProfile) {
    DateTime nextPeriodDate;
    try {
      nextPeriodDate = _advancedNextPeriodPrediction(periodRecords, userProfile);
    } catch (e) {
      debugPrint('高级下次经期预测失败，使用用户设置的周期长度: $e');
      nextPeriodDate = periodRecords.first.date.add(Duration(days: userProfile.cycleLength));
    }
    
    DateTime ovulationDate;
    try {
      ovulationDate = _advancedOvulationPrediction(nextPeriodDate, periodRecords, userProfile);
    } catch (e) {
      debugPrint('高级排卵预测失败，使用简单计算: $e');
      ovulationDate = nextPeriodDate.subtract(const Duration(days: 14));
    }
    
    List<DateTime> fertilityWindow;
    try {
      fertilityWindow = _calculateAdvancedFertilityWindow(ovulationDate, periodRecords, userProfile);
    } catch (e) {
      debugPrint('高级生育窗口计算失败，使用默认窗口: $e');
      fertilityWindow = List.generate(7, (i) => ovulationDate.subtract(Duration(days: 5 - i)));
    }
    
    int confidenceLevel;
    try {
      confidenceLevel = _calculatePredictionConfidence(periodRecords, userProfile);
    } catch (e) {
      debugPrint('计算预测可信度失败，使用默认值: $e');
      confidenceLevel = periodRecords.length >= 3 ? 70 : 50;
    }
    
    Map<DateTime, double> pregnancyRates;
    try {
      pregnancyRates = _calculateAdvancedPregnancyRates(ovulationDate, userProfile);
    } catch (e) {
      debugPrint('计算怀孕几率失败，使用简化计算: $e');
      pregnancyRates = {};
      for (int i = -3; i <= 3; i++) {
        final date = ovulationDate.add(Duration(days: i));
        double rate;
        if (i == 0 || i == 1) {
          rate = 25.0;
        } else if (i == -1 || i == 2) {
          rate = 15.0;
        } else {
          rate = 5.0;
        }
        pregnancyRates[date] = rate;
      }
    }
    
    return PredictionResult(
      nextPeriodDate: nextPeriodDate,
      ovulationDate: ovulationDate,
      fertilityWindow: fertilityWindow,
      confidenceLevel: confidenceLevel,
      pregnancyRates: pregnancyRates,
      predictedCycleLength: nextPeriodDate.difference(periodRecords.first.date).inDays,
    );
  }
  
  Future<CycleTrend> analyzeCycleTrend(UserProfile userProfile) async {
    try {
      final records = await _dataService.loadPeriodRecords();
      final periodRecords = records.where((r) => r.isPeriod).toList()
        ..sort((a, b) => b.date.compareTo(a.date));
      
      if (periodRecords.length < 4) {
        return CycleTrend.stable; 

      }
      
      
      final cycleLengths = <int>[];
      for (int i = 1; i < periodRecords.length; i++) {
        final daysBetween = periodRecords[i-1].date.difference(periodRecords[i].date).inDays;
        if (daysBetween >= 21 && daysBetween <= 45) {
          cycleLengths.add(daysBetween);
        }
      }
      
      if (cycleLengths.length < 3) {
        return CycleTrend.stable;
      }
      
      
      final slope = _calculateLinearRegressionSlope(cycleLengths);
      
      if (slope > 0.5) {
        return CycleTrend.lengthening; 

      } else if (slope < -0.5) {
        return CycleTrend.shortening; 

      } else {
        return CycleTrend.stable; 

      }
    } catch (e) {
      debugPrint('周期趋势分析失败: $e');
      return CycleTrend.stable;
    }
  }
  
  
  double _calculateWeightedMovingAverage(List<int> values) {
    double weightedSum = 0;
    double totalWeight = 0;
    
    for (int i = 0; i < values.length; i++) {
      final weight = i + 1; 

      weightedSum += values[i] * weight;
      totalWeight += weight;
    }
    
    return weightedSum / totalWeight;
  }
  
  
  double _calculateExponentialSmoothing(List<int> values) {
    const double alpha = 0.3; 

    double smoothed = values.first.toDouble();
    
    for (int i = 1; i < values.length; i++) {
      smoothed = alpha * values[i] + (1 - alpha) * smoothed;
    }
    
    return smoothed;
  }
  
  
  double _calculateLinearRegression(List<int> values) {
    if (values.length < 2) return values.first.toDouble();
    
    final n = values.length;
    double sumX = 0, sumY = 0, sumXY = 0, sumX2 = 0;
    
    for (int i = 0; i < n; i++) {
      sumX += i;
      sumY += values[i];
      sumXY += i * values[i];
      sumX2 += i * i;
    }
    
    final slope = (n * sumXY - sumX * sumY) / (n * sumX2 - sumX * sumX);
    final intercept = (sumY - slope * sumX) / n;
    
    
    return intercept + slope * n;
  }
  
  
  double _calculateLinearRegressionSlope(List<int> values) {
    if (values.length < 2) return 0.0;
    
    final n = values.length;
    double sumX = 0, sumY = 0, sumXY = 0, sumX2 = 0;
    
    for (int i = 0; i < n; i++) {
      sumX += i;
      sumY += values[i];
      sumXY += i * values[i];
      sumX2 += i * i;
    }
    
    return (n * sumXY - sumX * sumY) / (n * sumX2 - sumX * sumX);
  }
  
  
  int _applyIndividualFactors(int baseLength, List<PeriodModel> periodRecords, UserProfile userProfile) {
    int adjusted = baseLength;
    
    
    final age = _calculateAge(userProfile.birthDate);
    if (age < 20) {
      adjusted = (adjusted + 0.5).round(); 

    } else if (age > 40) {
      adjusted = (adjusted - 0.5).round(); 

    }
    
    
    if (userProfile.height > 0 && userProfile.weight > 0) {
      final heightInMeters = userProfile.height / 100;
      final bmi = userProfile.weight / (heightInMeters * heightInMeters);
      
      if (bmi < 18.5) {
        adjusted = (adjusted + 1.0).round(); 

      } else if (bmi > 35) {
        adjusted = (adjusted + 1.5).round(); 

      }
    }
    
    
    if (userProfile.healthConditions.isNotEmpty) {
      for (var condition in userProfile.healthConditions) {
        if (condition.contains('多囊')) {
          adjusted = (adjusted + 2.0).round();
        } else if (condition.contains('甲状腺')) {
          adjusted = (adjusted + 1.0).round();
        }
      }
    }
    
    
    if (userProfile.isUsingBirthControl) {
      adjusted = userProfile.cycleLength; 

    }
    
    
    return adjusted.clamp(21, 45);
  }
  
  
  
  
  double _calculateCycleStandardDeviation(List<PeriodModel> periodRecords) {
    if (periodRecords.length < 3) return 0.0;
    
    final cycleLengths = <int>[];
    for (int i = 1; i < periodRecords.length; i++) {
      final days = periodRecords[i-1].date.difference(periodRecords[i].date).inDays;
      if (days >= 21 && days <= 45) {
        cycleLengths.add(days);
      }
    }
    
    if (cycleLengths.length < 2) return 0.0;
    
    final mean = cycleLengths.reduce((a, b) => a + b) / cycleLengths.length;
    double sumSquaredDiff = 0;
    
    for (var length in cycleLengths) {
      sumSquaredDiff += math.pow(length - mean, 2);
    }
    
    return math.sqrt(sumSquaredDiff / cycleLengths.length);
  }
  
  
  int _calculateAge(DateTime? birthDate) {
    if (birthDate == null) return 25;
    final now = DateTime.now();
    int age = now.year - birthDate.year;
    if (now.month < birthDate.month || 
        (now.month == birthDate.month && now.day < birthDate.day)) {
      age--;
    }
    return age.clamp(12, 60); 

  }
  
  

}


class PredictionResult {
  final DateTime nextPeriodDate;
  final DateTime ovulationDate;
  final List<DateTime> fertilityWindow;
  final int confidenceLevel; 

  final Map<DateTime, double> pregnancyRates;
  final int predictedCycleLength;
  
  PredictionResult({
    required this.nextPeriodDate,
    required this.ovulationDate,
    required this.fertilityWindow,
    required this.confidenceLevel,
    required this.pregnancyRates,
    required this.predictedCycleLength,
  });
  
  
  bool isInFertilityWindow(DateTime date) {
    return fertilityWindow.any((windowDate) => 
      windowDate.year == date.year && 
      windowDate.month == date.month && 
      windowDate.day == date.day
    );
  }
  
  
  double getPregnancyRateForDate(DateTime date) {
    
    for (var entry in pregnancyRates.entries) {
      if (entry.key.year == date.year && 
          entry.key.month == date.month && 
          entry.key.day == date.day) {
        return entry.value;
      }
    }
    
    
    return 3.2;
  }
}


enum CycleTrend {
  shortening, 

  stable,     

  lengthening 

}